#include <iostream>

using std::cout;
using std::endl;

class Base
{
public:
    Base()
    : _base(0)
    {
        cout << "Base()" << endl;
    }

    Base(long base)
    : _base(base)
    {
        cout << "Base(long)" << endl;
    }

    void show() const
    {
        cout << "Base::_base = " << _base << endl;
    }

    ~Base()
    {
        cout << "~Base()" << endl;
    }
private:
    long _base;
};

class Derived
: public Base
{
public:
    Derived()
    : Base(0)
    , _derived(0)
    {
        cout << "Derived()" << endl;
    }

    Derived(long base, long derived)
    : Base(base)
    , _derived(derived)
    {
        cout << "Derived(long, long)" << endl;
    }

    void print() const
    {
        show();
        cout << "Derived::_derived = " << _derived << endl;
    }

    ~Derived()
    {
        cout << "~Derived()" << endl;
    }
private:
    long _derived;
};

void test()
{
    Base base(100);
    base.show();

    cout << endl;
    Derived derived(111, 222);
    derived.print();

    cout << endl << "从派生类对象向基类对象进行转换" << endl;
    base = derived;//1、派生类对象是可以赋值给基类对象的,ok
    //Base &operator=(const Base &rhs)
    //const Base &rhs = derived
    base.show();

    cout << endl;
    Base &ref = derived;//2、基类的引用可以绑定到派生类对象,ok
    ref.show();

    cout << endl;
    Base *pbase = &derived;//3、基类的指针可以指向派生类对象,ok
    pbase->show();

}

void test2()
{
    Base base(22);//栈上
    base.show();

    cout << endl;
    Derived derived(1000, 2000);//栈上
    derived.print();
    cout << endl << "从基类对象向派生类对象进行转换" << endl;
    derived = base;//1、不能将基类的对象赋值给派生类的对象,error
    //Derived &operator=(const Derived &rhs)
    //const Derived &rhs = base;
    //
    cout << endl;
    Derived &ref = base;//2、不能将派生类的引用绑定到基类对象,error

    cout <<endl;
    //3、不能将派生类类型的指针指向基类对象,error
    Derived *pderived = &base;

    //此处是因为有强制转换
    Derived *pderived2 = static_cast<Derived *>(&base);//不安全的

    Base *pbase = &derived;
    Derived *pderived3 = static_cast<Derived *>(pbase);//安全的
}

int main(int argc, char *argv[])
{
    test2();
    return 0;
}

